// Base Zombie Class.
class SRKFMonster extends KFMonster
	hidecategories(AnimTweaks,DeRes,Force,Gib,Karma,Udamage,UnrealPawn)
	Abstract;

function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class<DamageType> damageType, optional int HitIndex )
{
	local bool bIsHeadshot;
	local KFPlayerReplicationInfo KFPRI;
	local float HeadShotCheckScale;

	if(InstigatedBy==None) return; //Flame
	if(damageType==None) return; //Flame

	LastDamagedBy = instigatedBy;
	LastDamagedByType = damageType;
	HitMomentum = VSize(momentum);
	LastHitLocation = hitlocation;
	LastMomentum = momentum;

	if ( KFPawn(instigatedBy) != none && instigatedBy.PlayerReplicationInfo != none )
	{
		KFPRI = KFPlayerReplicationInfo(instigatedBy.PlayerReplicationInfo);
	}

	// Zeds and fire dont mix.
	if ( class<KFWeaponDamageType>(damageType).default.bDealBurningDamage )
	{
		if( BurnDown<=0 || Damage > LastBurnDamage )
		{
			// LastBurnDamage variable is storing last burn damage (unperked) received,
			// which will be used to make additional damage per every burn tick (second).
			LastBurnDamage = Damage;
			// FireDamageClass variable stores damage type, which started zed's burning
			// and will be passed to this function again every next burn tick (as damageType argument)
			if (	damageType.Name == 'DamTypeTrenchgun' ||
					damageType.Name == 'DamTypeFlareRevolver' ||
					damageType.Name == 'DamTypeMAC10MPInc' ||
					damageType.Name == 'DamTypeMAC10MPIncW'
				)
			{
				FireDamageClass = damageType;
			}
			else
			{
				FireDamageClass = class'DamTypeFlamethrowerW';
			}
		}

		if ( damageType.Name == 'DamTypeMAC10MPIncW' || damageType.Name == 'DamTypeMAC10MPInc' )
		{
			Damage *= 1.5; // Increase burn damage 1.5 times, except MAC10.
		}

		// BurnDown variable indicates how many ticks are remaining for zed to burn.
		// It is 0, when zed isn't burning (or stopped burning).
		// So all the code below will be executed only, if zed isn't already burning
		if( BurnDown<=0 )
		{
			if( HeatAmount>4 || Damage >= 15 )
			{
				bBurnified = true;
				BurnDown = 10; // Inits burn tick count to 10
				GroundSpeed *= 0.80; // Lowers movement speed by 20%
				BurnInstigator = instigatedBy;
				SetTimer(1.0,false); // Sets timer function to be executed each second
			}
			else HeatAmount++;
		}
	}

	if ( !bDecapitated && class<KFWeaponDamageType>(damageType)!=none &&
		class<KFWeaponDamageType>(damageType).default.bCheckForHeadShots )
	{
		HeadShotCheckScale = 1.0;

		// Do larger headshot checks if it is a melee attach
		if( class<DamTypeMelee>(damageType) != none )
		{
			HeadShotCheckScale *= 1.25;
		}

		bIsHeadShot = IsHeadShot(hitlocation, normal(momentum), HeadShotCheckScale);
		bLaserSightedEBRM14Headshotted = bIsHeadshot && M14EBRBattleRifle(instigatedBy.Weapon) != none && M14EBRBattleRifle(instigatedBy.Weapon).bLaserActive;
	}
	else
	{
		bLaserSightedEBRM14Headshotted = bLaserSightedEBRM14Headshotted && bDecapitated;
	}

	if ( KFPRI != none  )
	{
		if ( KFPRI.ClientVeteranSkill != none )
		{
			Damage = KFPRI.ClientVeteranSkill.Static.AddDamage(KFPRI, self, KFPawn(instigatedBy), Damage, DamageType);
		}
	}

	if ( damageType != none && LastDamagedBy.IsPlayerPawn() && LastDamagedBy.Controller != none )
	{
		if ( KFMonsterController(Controller) != none )
		{
			KFMonsterController(Controller).AddKillAssistant(LastDamagedBy.Controller, FMin(Health, Damage));
		}
	}

	if ( (bDecapitated || bIsHeadShot) && class<DamTypeBurned>(DamageType) == none && class<DamTypeFlamethrower>(DamageType) == none )
	{
		if(class<KFWeaponDamageType>(damageType)!=none)
			Damage = Damage * class<KFWeaponDamageType>(damageType).default.HeadShotDamageMult;

		if ( class<DamTypeMelee>(damageType) == none && KFPRI != none &&
			KFPRI.ClientVeteranSkill != none )
		{
			Damage = float(Damage) * KFPRI.ClientVeteranSkill.Static.GetHeadShotDamMulti(KFPRI, KFPawn(instigatedBy), DamageType);
		}

		LastDamageAmount = Damage;

		if( !bDecapitated )
		{
			if( bIsHeadShot )
			{
				// Play a sound when someone gets a headshot TODO: Put in the real sound here
				if( bIsHeadShot )
				{
					PlaySound(sound'KF_EnemyGlobalSndTwo.Impact_Skull', SLOT_None,2.0,true,500);
				}
				HeadHealth -= LastDamageAmount;
				if( HeadHealth <= 0 || Damage > Health )
				{
					RemoveHead();
				}
			}

			// Award headshot here, not when zombie died.
			if( bDecapitated && Class<KFWeaponDamageType>(damageType) != none && instigatedBy != none && 
				KFPlayerController(instigatedBy.Controller) != none )
			{
				bLaserSightedEBRM14Headshotted = 
					M14EBRBattleRifle(instigatedBy.Weapon) != none && 
					M14EBRBattleRifle(instigatedBy.Weapon).bLaserActive;
				Class<KFWeaponDamageType>(damageType).Static.ScoredHeadshot(KFSteamStatsAndAchievements(PlayerController(instigatedBy.Controller).SteamStatsAndAchievements), bLaserSightedEBRM14Headshotted);
			}
		}
	}

	// Client check for Gore FX
	//BodyPartRemoval(Damage,instigatedBy,hitlocation,momentum,damageType);

	if( Health-Damage > 0 && DamageType!=class'DamTypeFrag' && DamageType!=class'DamTypePipeBomb' && 
		DamageType!=class'DamTypeM79Grenade' && DamageType!=class'DamTypeM32Grenade' && 
		DamageType!=class'DamTypeM203Grenade' && DamageType.Name!='DamTypeFragW' && 
		DamageType.Name!='DamTypeM32W' && DamageType.Name!='DamTypeM79W' &&
		DamageType.Name!='DamTypeM203W' && DamageType.Name!='DamTypePipeBombW'
		)
	{
		Momentum = vect(0,0,0);
	}

	if(class<DamTypeVomit>(DamageType)!=none) // Same rules apply to zombies as players.
	{
		BileCount=7;
		BileInstigator = instigatedBy;
		if(NextBileTime< Level.TimeSeconds )
			NextBileTime = Level.TimeSeconds+BileFrequency;
	}

	if (	KFPRI != none && Health-Damage <= 0 && KFPRI.ClientVeteranSkill != none && 
			KFPRI.ClientVeteranSkill.static.KilledShouldExplode(KFPRI, KFPawn(instigatedBy)) )
	{
		Super(Skaarj).TakeDamage(Damage + 600, instigatedBy, hitLocation, momentum, damageType);
		HurtRadius(500, 1000, class'DamTypeFrag', 100000, Location);
	}
	else
	{
		Super(Skaarj).TakeDamage(Damage, instigatedBy, hitLocation, momentum, damageType);
	}

	if( bIsHeadShot && Health <= 0 )
	{
		KFGameType(Level.Game).DramaticEvent(0.03);
	}
	bBackstabbed = false;
}

function bool FlipOver()
{
	if( Physics==PHYS_Falling )
	{
		SetPhysics(PHYS_Walking);
	}

	bShotAnim = true;
	SetAnimAction('KnockDown');
	Acceleration = vect(0, 0, 0);
	Velocity.X = 0;
	Velocity.Y = 0;
	if(Controller!=none)
	{
		Controller.GoToState('WaitForAnim');
		KFMonsterController(Controller).bUseFreezeHack = True;
	}
	return true;
}

simulated function ToggleAuxCollision(bool newbCollision)
{
	if ( !newbCollision )
	{
		if(MyExtCollision!=none)
			SavedExtCollision = MyExtCollision.bCollideActors;
		if(MyExtCollision!=none)
			MyExtCollision.SetCollision(false);
	}
	else
	{
		if(MyExtCollision!=none)
			MyExtCollision.SetCollision(SavedExtCollision);
	}
}

defaultproperties
{
}
